package cn.edu.sgu.www.mhxysy.service.chongwu.impl;

import cn.edu.sgu.www.mhxysy.pager.Pager;
import cn.edu.sgu.www.mhxysy.consts.CustomDirectories;
import cn.edu.sgu.www.mhxysy.dto.chongwu.ChongwuSkillCategoryDTO;
import cn.edu.sgu.www.mhxysy.entity.chongwu.ChongwuSkill;
import cn.edu.sgu.www.mhxysy.entity.chongwu.ChongwuSkillCategory;
import cn.edu.sgu.www.mhxysy.enums.AuthStatus;
import cn.edu.sgu.www.mhxysy.exception.GlobalException;
import cn.edu.sgu.www.mhxysy.mapper.chongwu.ChongwuSkillCategoryMapper;
import cn.edu.sgu.www.mhxysy.mapper.chongwu.ChongwuSkillMapper;
import cn.edu.sgu.www.mhxysy.pager.chongwu.ChongwuSkillCategoryPager;
import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import cn.edu.sgu.www.mhxysy.service.chongwu.ChongwuSkillCategoryService;
import cn.edu.sgu.www.mhxysy.util.ImageUpdater;
import cn.edu.sgu.www.mhxysy.util.StringUtils;
import cn.edu.sgu.www.mhxysy.util.UploadUtils;
import cn.edu.sgu.www.mhxysy.util.WrapperUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@Service
public class ChongwuSkillCategoryServiceImpl implements ChongwuSkillCategoryService {

	private final UploadUtils uploadUtils;
	private final ImageUpdater imageUpdater;
	private final ChongwuSkillMapper chongwuSkillMapper;
	private final ChongwuSkillCategoryMapper chongwuSkillCategoryMapper;

	@Autowired
	public ChongwuSkillCategoryServiceImpl(
			UploadUtils uploadUtils,
			ImageUpdater imageUpdater,
			ChongwuSkillMapper chongwuSkillMapper,
			ChongwuSkillCategoryMapper chongwuSkillCategoryMapper) {
		this.uploadUtils = uploadUtils;
		this.imageUpdater = imageUpdater;
		this.chongwuSkillMapper = chongwuSkillMapper;
		this.chongwuSkillCategoryMapper = chongwuSkillCategoryMapper;
	}

	@Override
	public String upload(MultipartFile file) throws IOException {
		String directory = CustomDirectories.DIRECTORY_CWJN;

		return uploadUtils.upload(file, directory);
	}

	@Override
	public void insert(ChongwuSkillCategoryDTO chongwuSkillCategoryDTO) {
		chongwuSkillCategoryDTO.setId(null);

		boolean result = validateDuplicateName(chongwuSkillCategoryDTO);

		if (result) {
			ChongwuSkillCategory chongwuSkillCategory = toEntity(chongwuSkillCategoryDTO);

			chongwuSkillCategoryMapper.insert(chongwuSkillCategory);
		}
	}

	@Override
	public void updateById(ChongwuSkillCategoryDTO chongwuSkillCategoryDTO) {
		if (chongwuSkillCategoryDTO.getId() == null) {
			throw new GlobalException(ResponseCode.BAD_REQUEST, "宠物技能类型ID不能为空~");
		}

		boolean result = validateDuplicateName(chongwuSkillCategoryDTO);

		if (result) {
			ChongwuSkillCategory chongwuSkillCategory = toEntity(chongwuSkillCategoryDTO);

			chongwuSkillCategoryMapper.updateById(chongwuSkillCategory);
		}
	}

	@Override
	public void updateImageById(Integer id, String image) {
		imageUpdater.updateImageById(image, new Consumer<Object>() {
			@Override
			public void accept(Object o) {
				UpdateWrapper<ChongwuSkillCategory> updateWrapper = WrapperUtils.getUpdateWrapper(id, image);

				chongwuSkillCategoryMapper.update(updateWrapper.getEntity(), updateWrapper);
			}
		});
	}

	@Override
	public List<ChongwuSkillCategory> selectAll() {
		return chongwuSkillCategoryMapper.selectList(null);
	}

	@Override
	public ChongwuSkillCategory selectById(Integer id) {
		return chongwuSkillCategoryMapper.selectById(id);
	}

	@Override
	public List<ChongwuSkillCategory> selectByName(String name) {
		QueryWrapper<ChongwuSkillCategory> queryWrapper = new QueryWrapper<>();

		queryWrapper.like(
				StringUtils.isNotEmpty(name),
				"name", name
		);
		queryWrapper.orderByAsc("type", "id");

		return chongwuSkillCategoryMapper.selectList(queryWrapper);
	}

	@Override
	public List<ChongwuSkillCategory> getCanReplaceAuthSkills(String chongwuId) {
		QueryWrapper<ChongwuSkill> queryWrapper = new QueryWrapper<>();

		queryWrapper.eq("chongwu_id", chongwuId);
		queryWrapper.eq("auth_status", AuthStatus.YRZ.getValue());

		ChongwuSkill chongwuSkill = chongwuSkillMapper.selectOne(queryWrapper);

		if (chongwuSkill == null) {
			return new ArrayList<>();
		}

		Integer skillId = chongwuSkill.getSkillId();

		return chongwuSkillCategoryMapper.getCanReplacedAuthSkills(skillId);
	}

	@Override
	public Page<ChongwuSkillCategory> selectByPage(ChongwuSkillCategoryPager pager) {
		QueryWrapper<ChongwuSkillCategory> queryWrapper = new QueryWrapper<>();
		Page<ChongwuSkillCategory> page = Pager.ofPage(pager);

		queryWrapper.like(
				!StringUtils.isEmpty(pager.getName()),
				"name", pager.getName()
		);
		queryWrapper.eq(
				pager.getType() != null,
				"type", pager.getType()
		);

		return chongwuSkillCategoryMapper.selectPage(page, queryWrapper);
	}

	/**
	 * 验证技能名称是否重复
	 * @param chongwuSkillCategoryDTO 宠物技能信息
	 * @return 没有重复返回true，否则返回false
	 */
	private boolean validateDuplicateName(ChongwuSkillCategoryDTO chongwuSkillCategoryDTO) {
		QueryWrapper<ChongwuSkillCategory> queryWrapper = new QueryWrapper<>();

		queryWrapper.ne(
				chongwuSkillCategoryDTO.getId() != null,
				"id", chongwuSkillCategoryDTO.getId()
		);
		queryWrapper.eq("name", chongwuSkillCategoryDTO.getName());

		Long count = chongwuSkillCategoryMapper.selectCount(queryWrapper);

		if (count > 0) {
			throw new GlobalException(ResponseCode.CONFLICT, "技能名称重复~");
		}

		return true;
	}

	private ChongwuSkillCategory toEntity(ChongwuSkillCategoryDTO chongwuSkillCategoryDTO) {
		ChongwuSkillCategory chongwuSkillCategory = new ChongwuSkillCategory();

		chongwuSkillCategory.setId(chongwuSkillCategoryDTO.getId());
		chongwuSkillCategory.setName(chongwuSkillCategoryDTO.getName());
		chongwuSkillCategory.setType(chongwuSkillCategoryDTO.getType());
		chongwuSkillCategory.setNote(chongwuSkillCategoryDTO.getNote());
		chongwuSkillCategory.setScore(chongwuSkillCategoryDTO.getScore());
		chongwuSkillCategory.setVerifiable(chongwuSkillCategoryDTO.getVerifiable());

		return chongwuSkillCategory;
	}

}